<script setup>
import NCell, {buildCellSheet, buildForm} from "n-cell";
import {inject, onMounted, provide, reactive, ref, watch} from "vue";
import "jiuqi-ui";
import DriverDetail from "./processor/DriverDetail.vue";
import {Upload} from "view-ui-plus";
import {useDialog, useMessage} from "jiuqi-ui";
import NCELLCSS from "../../utils/NCELLCSS";


//================================================【组件通信】============================================================
//宏显式暴露
defineExpose({
    getSaveStatus, save, abandonPreSaveContent, closeEditorAndCheck
});
//请求工具
const context = inject('context')

//获取当前动因分组主键
const currentActiveTabKey = inject('currentActiveTabKey')

//当前模型ID
const {currAbcModelGuid} = inject('abcmodel')

//给父组件提供最新的 是否需要保存 情况
const tabDataChanged = inject('tabDataChanged')

//子组件控制参数  控制 显示 与 隐藏
const driverDetailVisiable = ref(false);
provide('driverDetailVisiable', driverDetailVisiable)

//当前激活页签名称
const currentActiveTabTitle = inject('currentActiveTabTitle')


//动因列表处理类型  新增 0  编辑 1
//注意与 DriverDetail组件中 processDimType 区分（processDriverType  是动因信息处理类型，processDimType 是动因中维度信息处理类型）
//动因列表编辑数据
const driverParam = reactive({processType: -1, processData: {}, time: ''})

//==================================================================【子组件传递参数，先展示，后编辑，最后保存】
function getTableValue(sonProcessedDriverInfo) {

    // 如果是新增操作 返回 的数据，只需要在原有数据基础上添加
    if (driverParam.processType === 0) {
        showAndEditList.push(sonProcessedDriverInfo)

        //刷新ncell
        refreshNcellContent()

        //新增操作，滚动条自动 跳转至 底部
        let rowHeight = ncell.getRowSize(1);
        let ncellRows = ncell.getRowCount();
        ncell.scrollTop(rowHeight * ncellRows);
    }

    // 如果是编辑操作 返回 的数据，需要先将原有数据（同一个动因ID的数据，删除）
    if (driverParam.processType === 1) {
        const findIndex = showAndEditList.findIndex(preFindItem => {
            return preFindItem.code === driverParam.processData.code
        })
        showAndEditList.splice(findIndex, 1, sonProcessedDriverInfo)
        message.success('编辑动因成功')

        //刷新ncell
        refreshNcellContent()
    }

    //重置动因处理状态
    driverParam.processType = -1
}

//==================================================================【生成新动因编码】
async function autoGenDriverCode(callback) {
    await context.getPlugin('http').post('abc/model/driver/autoGenDriverCode/' + currAbcModelGuid.value, showAndEditList)
        .then((res) => {
            callback(res.data.newDriverCode)
        })
}

//================================================【公用相关】============================================================
//颜色序列
const bkColor = ['#ffffff00', '#f9f9f9']
//当前鼠标移入单元格的颜色
const currMouseInColor = ref('')
// 用ref拿到div节点
const ncellDriverDiv = ref(null)
//消息组件
const message = useMessage()
//对话组件
const dialog = useDialog()
//保存按钮失效状态
const saveDisable = ref(true)

//==================================================================【设置布局样式】
function setNcellStyle() {
    //表头设置
    for (let j = 0; j < ncell.getColumnCount(); j++) {
        //字体大小
        ncell.setFontSize(0, j, NCELLCSS.fontSize)
        //字体加粗
        ncell.setBold(0, j, NCELLCSS.headerBold)
        //字体颜色
        ncell.setFontColor(0, j, NCELLCSS.fontColor)


        //对齐方式
        ncell.setHorizontal(0, j, 1)
        //缩进
        ncell.setIndent(0, j, 0.5)
        //背景颜色
        ncell.setBackgroundColor(0, j, '#f2f2f2')


        //高度
        ncell.setRowSize(0, 30);
        //宽度
        switch (j) {
            case 0:
                ncell.setColumnSize(j, 169)
                ncell.setData(0, j, '动因编码')
                break;
            case 1:
                ncell.setColumnSize(j, 169)
                ncell.setData(0, j, '动因名称')
                break;
            case 2:
                ncell.setColumnSize(j, 169)
                ncell.setData(0, j, '关联维度编码')
                break;
            case 3:
                ncell.setColumnSize(j, 158)
                ncell.setData(0, j, '关联维度名称')
                break;
            case 4:
                ncell.setColumnSize(j, 158)
                ncell.setData(0, j, '关联维成员编码')
                break;
            case 5:
                ncell.setColumnSize(j, 158)
                ncell.setData(0, j, '关联维成员名称')
                break;
            case 6:
                ncell.setColumnSize(j, 158)
                ncell.setData(0, j, '动因值编码')
                break;
            case 7:
                ncell.setColumnSize(j, 158)
                ncell.setData(0, j, '动因值名称')
                break;
            case 8:
                ncell.setColumnSize(j, 424)
                ncell.setData(0, j, '取数公式')
                break;
            case 9:
                //该列隐藏
                ncell.setData(0, j, '查询索引')
        }
    }


    //非表头行设置
    for (let i = 1; i < ncell.getRowCount(); i++) {
        //设置高度
        ncell.setRowSize(i, 30);
        for (let j = 0; j < ncell.getColumnCount(); j++) {
            //对齐方式
            ncell.setHorizontal(i, j, 1)
            //缩进
            ncell.setIndent(i, j, 0.5)

            //公式单元格 设置 等宽字体族
            if (j === 8)
                ncell.setFontName(i, j, 'Courier New')
        }
    }

    //隐藏行列号
    ncell.hiddenSerialNumberHeader()

    //处理因为隐藏行列号，导致边界消失情况
    ncell.setOffsetX(1)
    ncell.setOffsetY(1)

    //隐藏辅助列
    ncell.hiddenColumn(9)
}

//==================================================================【刷新ncell内容】
function refreshNcellContent() {
    //将旧数据删除
    ncell.deleteRows(0, rowCount.value)

    //设置显示行数
    let driverItemCount = 0;
    for (let i = 0; i < showAndEditList.length; i++) {
        let showAndEditListElement = showAndEditList[i];
        driverItemCount += showAndEditListElement.driverItemList.length
    }
    rowCount.value = driverItemCount + 1


    //添加新行
    ncell.insertRows(0, rowCount.value - 1);

    //设置布局样式
    setNcellStyle()

    //结果存在，显示数据
    if (rowCount.value !== 0) {
        processAndShowData(showAndEditList)
    }

    //设置页面内容只读
    setContentReadOnly()

    //设置保存按钮状态[可用]
    saveDisable.value = false

    //每次页面刷新 都 重置动因选择数组
    selectedDriverCodeArr.splice(0, selectedDriverCodeArr.length)
}

//==================================================================【关闭ncell编辑状态】
function closeEditorAndCheck() {
    //手动关闭编辑状态
    ncell.closeEditor();

    return !saveDisable.value
}

//==================================================================【ncell处理展示数据】
async function processAndShowData(showAndEditList) {
    //当前动因起始行,非表头的第一行
    let rowIndex = ref(1)
    for (let i = 0; i < showAndEditList.length; i++) {
        let driver = showAndEditList[i];
        ncell.setData(rowIndex.value, 0, driver.code)
        ncell.setData(rowIndex.value, 1, driver.name)
        for (let j = 0; j < driver.driverItemList.length; j++) {
            let driverItem = driver.driverItemList[j];
            ncell.setData(rowIndex.value, 2, driverItem.dimName)
            ncell.setData(rowIndex.value, 3, driverItem.dimTitle)
            ncell.setData(rowIndex.value, 4, driverItem.memberCode)
            ncell.setData(rowIndex.value, 5, driverItem.dimItemName)
            ncell.setData(rowIndex.value, 6, driverItem.code)
            ncell.setData(rowIndex.value, 7, driverItem.name)
            ncell.setData(rowIndex.value, 8, driverItem.driverItemFormula.formula)
            //对 columnIndex === 8 的公式列进行赋值操作，该列存在监听，只要更改就设置保存按钮状态为可用，破坏了初始化 不可用状态，此处进行编辑
            saveDisable.value = true
            let findIndex = ''
            //showAndEditList 中 第 i 项driverInfo
            findIndex += i
            findIndex += ','
            //driverInfo 中 第 j 项driverItemInfo
            findIndex += j
            ncell.setData(rowIndex.value, 9, findIndex)
            rowIndex.value = rowIndex.value + 1
        }
    }

    //当 表格中 除了标题行 外，还有数据行时，配置背景颜色
    if (ncell.getRowCount() > 1) {
        colorController()
    }

}

//==================================================================【颜色控制器】
function colorController() {
    //颜色序列下标
    let colorIndex = ref(0)

    //慢指针：showAndEditList中 driver的 下标
    const findIndex = ncell.getData(1,9)
    const findIndexArr = findIndex.split(',')
    const initDriverIndex = findIndexArr[0]
    let slowPoint = reactive({
        id:initDriverIndex,
        color:bkColor[colorIndex.value]
    })
    //快指针，当前动因id
    let fastPoint = ref('')

    for (let i = 2; i < rowCount.value; i++) {
        const findIndex = ncell.getData(i,9)
        const findIndexArr = findIndex.split(',')
        fastPoint.value =  findIndexArr[0]
        //当慢指针所指动因ID  与  快指针所指动因ID 一致，则同属一个动因，配置同一背景颜色
        if (fastPoint.value === slowPoint.id){
            //设置第 i 行背景颜色
            for (let j = 0; j < 10; j++) {
                ncell.setBackgroundColor(i,j,slowPoint.color)
            }
        }else {
            //当慢指针所指动因ID  与  快指针所指动因ID 不一致，则不同属一个动因，配置不同背景颜色
            //更新颜色序列下标
            colorIndex.value += 1
            colorIndex.value = colorIndex.value % 2

            //更新慢指针对应动因id
            slowPoint.id = fastPoint.value

            //更新慢指针所属颜色
            slowPoint.color = bkColor[colorIndex.value]

            //设置第 i 行背景颜色
            for (let j = 0; j < 10; j++) {
                ncell.setBackgroundColor(i,j,slowPoint.color)
            }
        }
    }
}

//设置内容只读[除 动因取数公式列 ]
function setContentReadOnly() {
    for (let i = 0; i < rowCount.value; i++) {
        for (let j = 0; j < 9; j++) {
            if (i > 0 && j === 8)
                ncell.setCellMode(i, j, 0)
            else
                ncell.setCellReadOnly(i, j)
        }
    }
}


//==================================================================【处理选择内容】
const selectedDriverCodeArr = reactive([])

function processSelectedNcellContent(selection) {
    //获取当前选择行下标数组
    const selectedRowIndexArr = reactive([])
    selectedRowIndexArr.push(selection.rowIndex)
    let nextRowIndex = selection.rowIndex
    for (let i = 0; i < selection.rowSpan; i++) {
        if (i !== selection.rowSpan - 1) {
            nextRowIndex += 1
            selectedRowIndexArr.push(nextRowIndex)
        }
    }

    //构建一个查询字典，记录动因ID是否加入数组
    const checkDriverArr = reactive([])
    for (let showAndEditListElement of showAndEditList) {
        const checkDriver = reactive({
            driverCode: showAndEditListElement.code,
            isAdd: false
        })
        checkDriverArr.push(checkDriver)
    }

    //生成所有选中动因项 的 动因ID数组(结合查询字典去除重复动因ID)
    for (let i = 0; i < selectedRowIndexArr.length; i++) {
        const findIndex = ncell.getData(selectedRowIndexArr[i], 9)
        const findIndexArr = findIndex.split(',')

        const containIndex = checkDriverArr.findIndex(driverItem => {
            return driverItem.driverCode === showAndEditList[findIndexArr[0]].code
        })

        let driverArrElement = checkDriverArr[containIndex];
        if (driverArrElement.isAdd === false) {
            driverArrElement.isAdd = true
            selectedDriverCodeArr.push(driverArrElement.driverCode)
        }
    }
}


//================================================【组件属性】============================================================
watch(currentActiveTabKey, (newValue, oldValue) => {
    //初次有值时进行初始化
    if (newValue !== '' && oldValue === '') {

        initDriversByDriverGroupId()

    } else {
        context.getPlugin('http').get(`abc/model/driver/list/${currentActiveTabKey.value}/${currAbcModelGuid.value}`).then((res) => {
            //装配数据
            showAndEditList.splice(0, showAndEditList.length, ...res.data.showList)
            refreshNcellContent()
            //设置保存按钮状态[不可用]
            saveDisable.value = true
        });
    }
})

//控制 “导出” 按钮显示与隐藏
watch(() => saveDisable.value, (newValue) => {
    exportDisable.value = !newValue

    //本组件 给 modelIndex 提供最新的 是否需要保存 情况，DriverGroupEntrance 给 modelIndex 提供具体的保存方法
    //saveDriver  abandonSaveDriver  是 DriverGroupEntrance 方法
    tabDataChanged(!newValue, 'saveDriver', 'abandonSaveDriver')
}, {deep: true})
//================================================【普通方法】============================================================
//==================================================================【设置ncell容器高度(初始设置)】
function abandonPreSaveContent() {
    return new Promise((resolve, reject) => {
        //获取数据库数据
        context.getPlugin('http').get(`abc/model/driver/list/${currentActiveTabKey.value}/${currAbcModelGuid.value}`).then((res) => {
            //装配数据
            showAndEditList.splice(0, showAndEditList.length, ...res.data.showList);
            refreshNcellContent();
            saveDisable.value = true
            resolve()
        }).catch(() => {
            reject()
        })
    });

}

//==================================================================【设置ncell容器高度(初始设置)】
let ncellContainerHeight = ref(0)

function setNcellContainerStyle() {
    ncellContainerHeight.value = document.body.clientHeight - 155
}

//==================================================================【根据 动因分组ID 获取 动因集合】

//表格展示数组（会根据编辑操作 动态更新）
const showAndEditList = reactive([])

//ncell 展示行数，需要从后端获取
const rowCount = ref(0)
// 构建页签
let cellSheet = reactive(null)
let data = reactive(null)


function initDriversByDriverGroupId() {
    //获取数据库数据
    context.getPlugin('http').get(`abc/model/driver/list/${currentActiveTabKey.value}/${currAbcModelGuid.value}`).then((res) => {
        //装配数据
        showAndEditList.splice(0, showAndEditList.length, ...res.data.showList)

        //设置显示行数
        rowCount.value = res.data.totalCount + 1

        //构建表样
        cellSheet = buildForm(rowCount.value, 10, 'cellSheet')
        data = buildCellSheet(cellSheet)

        //初始化ncell
        initNewCell();

        //结果存在，显示数据
        if (rowCount.value !== 0) {
            processAndShowData(showAndEditList)
        }


        //设置页面内容只读
        setContentReadOnly()


    })
}

//==================================================================【设置新报表组件】
//ncell对象
let ncell = reactive({})

function initNewCell() {
    // 创建表格实例
    ncell = new NCell(
        ncellDriverDiv.value,
        data,
        {},
        {forceShowGridline: true, resizeMode: 'all',justPasteData:true}
    )

    //设置布局样式
    setNcellStyle()

    //设置监听事件
    setNcellListenEvent()
}

//==================================================================【设置监听事件】
function setNcellListenEvent() {
    //设置ncell监听事件  选择单元格后触发
    ncell.on('beforeselectionchange', () => {
        //设置编辑按钮状态[可用]
        editDisable.value = false
        //设置删除按钮状态[可用]
        deleteDisable.value = false
    })

    //当 手动编辑 公式时，编辑保存按钮状态[可用]
    ncell.on('celldatachange', (rowIndex, columnIndex) => {
        if (columnIndex === 8) {
            //设置编辑按钮状态[可用]
            saveDisable.value = false;
        }
    })

    //鼠标进入单元格，给该单元格所在行设置背景颜色
    ncell.on('mousein', (res) => {
        //操作表头之下的行
        if (res.entity.r > 0) {
            //存储当前单元格颜色
            currMouseInColor.value = ncell.getBackgroundColor(res.entity.r, res.entity.c)
            for (let i = 0; i < ncell.getColumnCount(); i++) {
                ncell.setBackgroundColor(res.entity.r, i, '#E4F0FF')
            }
        }
    })

    //鼠标离开单元格，给该单元格所在行清除背景颜色
    ncell.on('mouseout', (res) => {
        if (res.entity.r > 0) {
            for (let i = 0; i < ncell.getColumnCount(); i++) {
                ncell.setBackgroundColor(res.entity.r, i, currMouseInColor.value)
            }
        }
    })
}


//==================================================================【顶部菜单---保存】
// 保存操作加载状态显示
const saveLoading = ref(false)

function save() {
    return new Promise((resolve, reject) => {
        //如果当前是显示状态，保存操作不执行
        if (saveLoading.value) {
            reject('保存失败')
            return
        }

        //执行保存操作时，保存按钮显示加载状态
        saveLoading.value = true

        //避免数据已经输入，因未失焦，导致数据不能保存
        ncell.closeEditor();

        const rowCount1 = ncell.getRowCount();

        //将 动因编码信息 和 公式信息 进行装配  [第一行是标题行  需要跳过]
        for (let i = 1; i < rowCount1; i++) {
            const findIndex = ncell.getData(i, 9)
            if (findIndex !== '') {
                const findIndexArr = findIndex.split(',')
                showAndEditList[findIndexArr[0]].driverItemList[findIndexArr[1]].driverItemFormula.formula = ncell.getData(i, 8)
            }
        }

        context.getPlugin('http').post(`abc/model/driver/driverCodeCheckViaOtherExistedDrivers/${currAbcModelGuid.value}/${currentActiveTabKey.value}`, showAndEditList)
            .then(res => {
                const driverCheckVo = res.data.driverCheckVo
                if (!driverCheckVo.checkPass) {
                    message.error('保存失败，动因编码（' + driverCheckVo.checkDriverCode + '）在动因分组（' + driverCheckVo.repeatDriverGroupTitle + '）中已经存在，请编辑')
                    reject()
                    saveLoading.value = false
                } else {
                    //保存操作(先删除 当前动因分组下所有动因 后添加 页面中所有动因)
                    context.getPlugin('http').post(`abc/model/driver/batchAdd/${currentActiveTabKey.value}`, showAndEditList).then(() => {

                        message.success('保存成功')
                        saveLoading.value = false
                        //设置保存按钮状态[不可用]
                        saveDisable.value = true
                        resolve()
                    }).catch(() => {
                        reject()
                    })
                }
            })
    });


}

//==================================================================【检测当前页面是否有未保存的信息】
function getSaveStatus() {
    return !saveDisable.value
}


//==================================================================【顶部菜单---添加动因】
function addDriverByNavigator() {
    driverParam.processType = 0
    driverDetailVisiable.value = true
}


//==================================================================【顶部菜单---删除动因】
const deleteDisable = ref(true)
const deleteLoading = ref(false)

function deleteDriver() {
    if (deleteLoading.value) {
        return
    }
    //加载状态开始
    deleteLoading.value = true

    dialog.warning({
        title: '提示', content: '确认删除动因吗？', onOk: () => {
            //获取选中信息
            const selection = ncell.getCurrentSelection()
            processSelectedNcellContent(selection)


            if (selectedDriverCodeArr.length > 0) {
                //检查 待删除动因是否被分摊关系引用
                const preDeleteDriverArr = showAndEditList.filter(filterItem => {
                    return selectedDriverCodeArr.findIndex(findItem => {
                        return findItem === filterItem.code
                    }) !== -1
                })


                context.getPlugin('http').post(`abc/model/driver/driverCodeCheckViaRelation/${currAbcModelGuid.value}`, preDeleteDriverArr)
                    .then((res) => {
                        const {hasQuote, quotedDriverNames} = res.data
                        if (hasQuote) {
                            message.warning(`${quotedDriverNames}存在引用，删除失败。`)
                        } else {
                            //确认未被引用，进行前端数据删除，（后续保存时，进行数据库持久化）
                            const afterDeletedDrivers = showAndEditList.filter(filterItem => {
                                return selectedDriverCodeArr.findIndex(findItem => {
                                    return findItem === filterItem.code
                                }) === -1
                            })
                            showAndEditList.splice(0, showAndEditList.length, ...afterDeletedDrivers)
                        }

                        //刷新数据
                        refreshNcellContent()

                        //设置编辑按钮状态[不可用]
                        editDisable.value = true
                        //设置删除按钮状态[不可用]
                        deleteDisable.value = true
                        //每次操作后 将选择的 动因编码数组 置空
                        selectedDriverCodeArr.splice(0, selectedDriverCodeArr.length)
                        //每次操作后 将ncell 单元格的选中状态 取消
                        ncell.clearSelections()
                        //加载状态结束
                        deleteLoading.value = false
                    })
            }
        },
        onCancel: () => {
            //加载状态结束
            deleteLoading.value = false
        }
    });
}


//==================================================================【顶部菜单---编辑动因】
const editDisable = ref(true)

function editDriver() {
    //获取选中信息
    const selection = ncell.getCurrentSelection()
    processSelectedNcellContent(selection)

    if (selectedDriverCodeArr.length > 1) {
        message.warning('不可编辑多个动因')
    }

    if (selectedDriverCodeArr.length === 1) {
        driverParam.processType = 1
        const tempDriver = showAndEditList.filter(filterItem => {
            return filterItem.code === selectedDriverCodeArr[0]
        })
        driverParam.processData = tempDriver[0]

        //重复点击同一个动因分组时，改变时间值处罚监听
        driverParam.time = new Date().getTime()

        driverDetailVisiable.value = true
    }

    //设置编辑按钮状态[不可用]
    editDisable.value = true
    //设置删除按钮状态[不可用]
    deleteDisable.value = true
    //每次操作后 将选择的 动因编码数组 置空
    selectedDriverCodeArr.splice(0, selectedDriverCodeArr.length)
    //每次操作后 将ncell 单元格的选中状态 取消
    ncell.clearSelections()
}

//==================================================================【顶部菜单---数据导入】
let file = new reactive(null)

//导入按钮加载状态
const dataImportLoading = ref(false)

async function dataImport(uploadFile) {
    if (dataImportLoading.value) {
        return
    }
    //开始加载状态
    dataImportLoading.value = true

    file = uploadFile;

    //阻止默认事件，使用context上传文件
    await context.getPlugin('http').post(`abc/model/driver/import/${currAbcModelGuid.value}/${currentActiveTabKey.value}`, {'file': file}, {
        headers: {
            'Content-Type': 'multipart/form-data',
            'x-requested-with': "XMLHttpRequest",
            // eslint-disable-next-line no-undef
            'Authorization': context.getPlugin('http').getConfig().headers.Authorization
        }
    }).then(async (res) => {
        if (res.data.checkPassAndImportSuccess) {
            //从数据库中获取 刚才导入的数据
            await context.getPlugin('http').get(`abc/model/driver/list/${currentActiveTabKey.value}/${currAbcModelGuid.value}`).then((res) => {
                //装配数据
                showAndEditList.splice(0, showAndEditList.length, ...res.data.showList)

                //刷新数据
                refreshNcellContent()

                //refreshNcellContent()操作会将 保存 按钮 设置为 [可用]，导入 操作 自动入库，需要将 保存 按钮 设置为 [不可用]
                saveDisable.value = true

                message.success("导入成功")

                //结束加载状态
                dataImportLoading.value = false
            });

        } else {
            useDialog().error({content: res.data.errorInfo})
            //结束加载状态
            dataImportLoading.value = false
        }
    }).catch(() => {
        message.error('导入失败')
        //结束加载状态
        dataImportLoading.value = false
    })

    //阻止默认上传事件
    return false
}

//==================================================================【顶部菜单---数据导出】
// 导出按钮加载状态
const dataOutputLoading = ref(false)
// 导出按钮失效状态
const exportDisable = ref(false)

function dataOutput() {
    if (dataOutputLoading.value) {
        return
    }
    //开始加载状态
    dataOutputLoading.value = true
    context.getPlugin('http').post(`abc/model/driver/export/${currentActiveTabKey.value}/${currAbcModelGuid.value}`, {}, {
        headers: {
            // 'Content-Type': 'application/octet-stream',
            'x-requested-with': "XMLHttpRequest",
            // eslint-disable-next-line no-undef
            'Authorization': context.getPlugin('http').getConfig().headers.Authorization
        },
        responseType: 'blob'
    }).then(res => {
        const blob = new Blob([res.data], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});
        const url = window.URL.createObjectURL(blob)
        const aLink = document.createElement('a')
        aLink.style.display = 'none'
        aLink.href = url

        const exportTitle = '动因' + '-' + currentActiveTabTitle.value + '.xlsx'
        aLink.setAttribute('download', exportTitle)

        document.body.appendChild(aLink)
        aLink.click()
        document.body.removeChild(aLink) // 下载完成移除元素
        window.URL.revokeObjectURL(url) // 释放掉blob对象

        message.success("导出成功")

        //结束加载状态
        dataOutputLoading.value = false
    }).catch(() => {
        message.error("导出失败")
        //结束加载状态
        dataOutputLoading.value = false
    });
}

//================================================【生命周期】============================================================
//mounted 初始化页面完成进行操作
onMounted(async () => {

    //当浏览器页面大小改变，ncell表格高度对应更新
    window.addEventListener('resize', function () {
        ncellContainerHeight.value = document.body.clientHeight - 155
    })
    setNcellContainerStyle()
})
</script>

<template>
    <j-layout class="layout">
        <!--<editor-fold desc="头部菜单栏">-->
        <j-header class="toolbar">
            <j-space :size="16">
                <j-button @click="save" :disabled="saveDisable" :loading='saveLoading'>保存</j-button>
                <j-button @click="addDriverByNavigator">添加</j-button>
                <j-button @click="editDriver" :disabled="editDisable">编辑</j-button>
                <j-button @click="deleteDriver" :disabled="deleteDisable" :loading='deleteLoading'>删除</j-button>
                <Upload :before-upload="dataImport" :disabled="dataImportLoading">
                    <j-button :loading="dataImportLoading">导入</j-button>
                </Upload>
                <j-button @click="dataOutput" :disabled="exportDisable" :loading="dataOutputLoading">导出</j-button>
            </j-space>
        </j-header>
        <!--</editor-fold>-->

        <!--<editor-fold desc="页面主体内容">-->
        <j-content class="contentContainer">
            <div ref="ncellDriverDiv" style="width: 100%" :style="{height:ncellContainerHeight+'px'}"/>
        </j-content>
        <!--</editor-fold>-->
    </j-layout>
    <DriverDetail
            :show="driverDetailVisiable"
            :driver-param="driverParam"
            :pre-save-driver-arr="showAndEditList"
            @selfConfirmReturnParam="getTableValue"
            @autoGenDriverCode="autoGenDriverCode"
    >
    </DriverDetail>
</template>

<style scoped>
.toolbar {
    position: relative;
    height: 50px !important;
    line-height: 50px;
}

.ivu-upload {
    display: flex !important;
    align-items: center !important;
}

:deep(.ivu-upload-select) {
    display: flex !important;
}

.contentContainer {
    width: 100%;
    height: 100%;
}
</style>
